home *** CD-ROM | disk | FTP | other *** search
/ APDL Eductation Resources / APDL Eductation Resources.iso / programs / graphics / gif2rpc / source / s / map8_quick < prev   
Encoding:
Text File  |  1996-01-11  |  5.3 KB  |  164 lines

  1. ; map8_quick.s
  2. ; MACHINE:     RISC OS
  3. ; LANGUAGE:    OBJASM assembler
  4. ; AUTHOR:      Cy Booker, cy@cheepnis.demon.co.uk
  5. ; LICENSE:     FreeWare, Copyright (c) Cy Booker 1996
  6. ; PURPOSE:     Given an arbitary 48-bit colour, what is the closest 8-bit colour number?
  7. ;              assuming the default 256 colour palette
  8. ;
  9. ; Note the algorithm used is based on the one inside Acorns' ChangeFSI
  10. ; but modified slightly by me to be faster and more accurate
  11. ;
  12. ; ChangeFSI's algorithm is the same as the one posted to UseNet
  13. ;
  14. ;       Message-ID: <12463@acorn.co.uk>
  15. ;       Date: 30 Jan 92 12:20:23 GMT
  16. ;       From: RWilson@acorn.co.uk
  17. ;       Subject: How to find the closest colour out of the RISC OS 256
  18. ;
  19. ; And so I hereby acknowledge that I'm using their spiffy code
  20. ;
  21. ; in middle we have |intensity-difference| <-- 0x3fff
  22. ; so |i|^2 <= 0x0fff8001
  23. ; and so |d|^2 <= 3.|i|^2 <= 0x2ffe8003
  24. ; so total scale must be < 2^32/(|d|^2) , ie < ~5
  25. ; but this does not leave enough accuracy really, so we shift by a bit
  26. ;
  27. ; the weights we want are:
  28. ;       Red     * 0.212671   * 14 ~=  3 / 4 ~= 0x0.c
  29. ;       Green   * 0.715160   * 14 ~= 10 / 4 ~= 0x2.8
  30. ;       Blue    * 0.072169   * 14 ~=  1 / 4 ~= 0x0.4
  31. ;
  32. ; note we will divide by 2 to ensure total < 2^32
  33. ; (ie 0x3fff*0x3fff*3*14/2 < 2^32)
  34. ;
  35.  
  36.  
  37.         GET     OS:Hdr.os
  38.  
  39. ;
  40.  
  41.         EXPORT  map_scaled_rgb_to_8bpp_colour_number_quick
  42.  
  43.         AREA |ARM$$code|, CODE, READONLY
  44.  
  45.         ROUT
  46.  
  47. ;
  48. ; In    R0 -> structure
  49. ;               structure[3] = pointer to array of {red, green, blue} for default wimp palette
  50. ;               structure[4] = number of entries in array (== 256)
  51. ;       R1 = red nominally [0, 0xffff], but clipped as necessary
  52. ;       R2 = green nominally [0, 0xffff], but clipped as necessary
  53. ;       R3 = blue nominally [0, 0xffff], but clipped as necessary
  54. ; Out   R0 <-- palette entry %BGgRbrTt (bits 8-31 are zero)
  55. ;       structure[0] = error in approximating red intensity
  56. ;       structure[1] = error in approximating green intensity
  57. ;       structure[2] = error in approximating blue intensity
  58. ;
  59.  
  60.         ROUT
  61.  
  62. map_scaled_rgb_to_8bpp_colour_number_quick
  63.  
  64. str     RN      a1
  65. red     RN      a2
  66. grn     RN      a3
  67. blu     RN      a4
  68. tint    RN      v1
  69. dmin    RN      v2
  70. dist    RN      v3
  71. colour  RN      v4
  72. best    RN      v5
  73. mtint   RN      v6
  74. x       RN      ip
  75. y       RN      lr
  76.  
  77. dr      RN      tint
  78. dg      RN      dmin
  79. db      RN      dist
  80.  
  81. bits    * 16                    ; the inline weighting functions assume bits <= 16
  82.  
  83.         STMFD   sp!, {v1-v6, lr}
  84.         MOV     lr, #1 << bits
  85.         CMP     red, lr                              ; ensure in range [0, 0xffff]
  86.         MOVHS   red, #0
  87.         SUBGE   red, lr, #1
  88.         CMP     grn, lr
  89.         MOVHS   grn, #0
  90.         SUBGE   grn, lr, #1
  91.         CMP     blu, lr
  92.         MOVHS   blu, #0
  93.         SUBGE   blu, lr, #1
  94. ;
  95.         MOV     dmin, #&ffffffff
  96.         MOV     tint, #&30 << 23
  97. 0
  98.         RSB     mtint, tint, #&20 << 23
  99.  
  100.         SUB     y, blu, blu, LSR #4                     ; y ~= blu * 16 / 17
  101.         ADDS    x, mtint, y, LSL #31 - bits
  102.         MOVVSS  x, #&c0 << 23
  103.         MOVMI   x, #0
  104.         AND     x, x, #&c0 << 23                        ; %0Bb0 0000 0000 0000 0000 0000 0000 0000
  105.         ADD     x, x, tint                              ; %0BbT t000 0000 0000 0000 0000 0000 0000
  106.         ADD     colour, x, x, LSR #4                    ; colour = blu << 23
  107.         [ bits > 8
  108.         ADD     x, colour, colour, LSR #8               ; %0BbT tBbT tBbT tBbT t000 0000 0000 0000
  109.          [ bits > 16
  110.           ADD     x, x, x, LSR #16                      ; %0BbT tBbT tBbT tBbT tBbT tBbT tBbT tBbT
  111.          ]
  112.          SUBS    y, blu, x, LSR #31 - bits              ; bug in changefsi here!
  113.         |
  114.          SUBS    y, blu, colour, LSR #31 - bits
  115.         ]
  116.         RSBLT   y, y, #0                                ; speeds up MUL instruction
  117.  
  118.         MUL     dist, y, y                              ; dist = blu * 0x1.0
  119.  
  120.         SUB     y, grn, grn, LSR #4
  121.         ADDS    x, mtint, y, LSL #31 - bits
  122.         MOVVSS  x, #&c0 << 23
  123.         MOVMI   x, #0
  124.         AND     x, x, #&c0 << 23
  125.         ADD     x, tint, x
  126.         ADD     x, x, x, LSR #4
  127.         ORR     colour, colour, x, LSR #8               ; colour |= grn << 15
  128.         [ bits > 8
  129.         ADD     x, x, x, LSR #8
  130.         [ bits > 16
  131.         ADD     x, x, x, LSR #16
  132.         ]
  133.         ]
  134.         SUBS    y, grn, x, LSR #31 - bits
  135.         RSBLT   y, y, #0
  136.  
  137.         MUL     x, y, y
  138.         MOV     x, x, LSL #1
  139.         ADD     dist, x, dist, LSR #2                   ; dist = blu * 0x0.4 + grn * 0x2.0
  140.         ADD     dist, dist, x, LSR #3                   ; dist = blu * 0x0.4 + grn * 0x2.8
  141.  
  142.         SUB     y, red, red, LSR #4
  143.         ADDS    x, mtint, y, LSL #31 - bits
  144.         MOVVSS  x, #&c0 << 23
  145.         MOVMI   x, #0
  146.         AND     x, x, #&c0 << 23
  147.         ADD     x, tint, x
  148.         ADD     x, x, x, LSR #4
  149.         ORR     colour, colour, x, LSR #16              ; colour |= red << 7
  150.         [ bits > 8
  151.         ADD     x, x, x, LSR #8
  152.         [ bits > 16
  153.         ADD     x, x, x, LSR #16
  154.         ]
  155.         ]
  156.         SUBS    y, red, x, LSR #31 - bits
  157.         RSBLT   y, y, #0
  158.  
  159.         MULNE   x, y, y
  160.         ADDNE   dist, dist, x, LSR #2                   ; dist = blu * 0x0.4 + grn * 0x2.8 + red * 0x0.4
  161.         ADDNE   dist, dist, x, LSR #1                   ; dist = blu * 0x0.4 + grn * 0x2.8 + red * 0x0.c
  162.  
  163.         CMP     dist, dmin
  164.